package com.example.springmvc.config;

import com.example.springmvc.common.WebResult;
import com.example.springmvc.exception.BusinessException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * 统一异常处理
 *
 * @author fanhang
 */
@RestControllerAdvice
public class WebExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(WebExceptionHandler.class);

    @ExceptionHandler({MissingServletRequestParameterException.class})
    public WebResult<?> missingServletRequestParameterException(MissingServletRequestParameterException ex) {
        log.warn("MissingServletRequestParameterException: {}", ex.getMessage());
        return WebResult.error("param " + ex.getParameterName() + " error");
    }

    @ExceptionHandler({IllegalArgumentException.class})
    public WebResult<?> illegalArgumentException(IllegalArgumentException ex) {
        log.warn("IllegalArgumentException: {}", ex.getMessage());
        return WebResult.error(ex.getMessage());
    }

    @ExceptionHandler({IllegalStateException.class})
    public WebResult<?> illegalStateException(IllegalStateException ex) {
        log.warn("IllegalStateException: {}", ex.getMessage());
        return WebResult.error(ex.getMessage());
    }

    @ExceptionHandler({UnsupportedOperationException.class})
    public WebResult<?> unsupportedOperationException(UnsupportedOperationException ex) {
        log.warn("UnsupportedOperationException: {}", ex.getMessage());
        return WebResult.error(ex.getMessage());
    }

    @ExceptionHandler({HttpMessageConversionException.class})
    public WebResult<?> httpMessageConversionException(HttpMessageConversionException ex) {
        log.warn("HttpMessageConversionException:{}", ex.getMessage());
        return WebResult.error(ex.getMessage());
    }

    @ExceptionHandler({NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public WebResult<?> noHandlerFoundException(NoHandlerFoundException ex) {
        log.warn("NoHandlerFoundException: {}", ex.getMessage());
        return WebResult.error(404, ex.getMessage());
    }

    /**
     * javax-validation 自动验证
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    public WebResult<?> methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        log.warn("MethodArgumentNotValidException: {} {}", ex.getBindingResult().getAllErrors().get(0).getObjectName(),
            ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
        return WebResult.error(ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    @ExceptionHandler({BusinessException.class})
    public WebResult<?> businessException(BusinessException ex) {
        log.error("BusinessException: code:{}, message: {}", ex.getCode(), ex.getMessage());
        return WebResult.error(ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler({Throwable.class})
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public WebResult<?> errorThrowable(Throwable ex) {
        log.error("unkonw exception: ", ex);
        return WebResult.error(ex.getMessage());
    }
}
